﻿using Newtonsoft.Json;
using SheXiangTou.Beans;
using SheXiangTou.Beans.LocalModel;
using SheXiangTou.Controller;
using SheXiangTou.Tools;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Xml;

namespace SheXiangTou.Services
{
    public class MacService
    {
        public static int Login_Id = -1;
     
        public static CHCNetSDK.MSGCallBack_V31 m_falarmData_V31 = null;

        public bool AddUser(UserCardMQ userCardMQ)
        {
            byte[] userStream = null;
            try
            {
                byte[] imgStream = Convert.FromBase64String(userCardMQ.photo);
                if (!string.IsNullOrEmpty(userCardMQ.photo))
                {
                    string xmlfile = AppDomain.CurrentDomain.BaseDirectory + "Userinfo.xml";
                    if (File.Exists(xmlfile))
                    {
                        XmlDocument document = new XmlDocument();
                        document.Load(xmlfile);
                        XmlNodeList names = document.GetElementsByTagName("name");
                        names[0].InnerText = userCardMQ.userName;
                        XmlNodeList sexs = document.GetElementsByTagName("sex");
                        sexs[0].InnerText = userCardMQ.sex.Equals("男") ? "male" : "female";
                        XmlNodeList cerNums = document.GetElementsByTagName("certificateNumber");
                        cerNums[0].InnerText = userCardMQ.phone;
                        XmlNodeList cerNums2 = document.GetElementsByTagName("certificateType");
                        cerNums2[0].InnerText = "";//不填写 表示证件类型为其他
                        XmlNodeList cerNums3 = document.GetElementsByTagName("customHumanID");
                        cerNums3[0].InnerText = userCardMQ.phone;//不填写 表示证件类型为其他
                        if (userCardMQ.idcard != null && userCardMQ.idcard.Length == 18)
                        {
                            string bithday = userCardMQ.idcard.Substring(6, 8);
                            DateTime b = DateTime.ParseExact(bithday, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture);
                            XmlNodeList bornTimes = document.GetElementsByTagName("bornTime");
                            bornTimes[0].InnerText = b.ToString("yyyy-MM-ddThh:mm:ssZ");
                        }
                        string context = document.OuterXml;
                        if (string.IsNullOrEmpty(context) == false)
                        {
                            string[] strs = new string[2];
                            strs[0] = context.Substring(0, 50);
                            strs[1] = context.Substring(50, context.Length - 50);
                            strs[1] = strs[1].Replace(" ", string.Empty);
                            context = $"{strs[0]}{strs[1]}";
                        }
                        userStream = Encoding.UTF8.GetBytes(context);
                    }
                }
                CHCNetSDK.NET_DVR_FACELIB_COND lpInBuffer = new CHCNetSDK.NET_DVR_FACELIB_COND();
                Int32 nInSize = Marshal.SizeOf(lpInBuffer);
                lpInBuffer.dwSize = (uint)nInSize;

                byte[] byFDID = Encoding.Default.GetBytes("");
                lpInBuffer.szFDID = new byte[256];
                byFDID.CopyTo(lpInBuffer.szFDID, 0);
                lpInBuffer.byConcurrent = 0;//不并发
                lpInBuffer.byCustomFaceLibID = 1;
                uint dwUploadType = (uint)CHCNetSDK.HKUploadType.IMPORT_DATA_TO_FACELIB;
                uint dwInBufferSize = (uint)nInSize;
                IntPtr lpOutBuffer = IntPtr.Zero;
                uint dwOutBufferSize = 0;

                IntPtr ptrPicCfg = Marshal.AllocHGlobal(nInSize);
                Marshal.StructureToPtr(lpInBuffer, ptrPicCfg, false);

                int lUploadHandle = CHCNetSDK.NET_DVR_UploadFile_V40(Login_Id, dwUploadType, ptrPicCfg, dwInBufferSize, null, lpOutBuffer, dwOutBufferSize);
                if (lUploadHandle < 0)
                {
                    uint i = CHCNetSDK.NET_DVR_GetLastError();
                    return false;
                }

                CHCNetSDK.NET_DVR_SEND_PARAM_IN pstruSendParamIN = new CHCNetSDK.NET_DVR_SEND_PARAM_IN();
                nInSize = Marshal.SizeOf(pstruSendParamIN);
                pstruSendParamIN.byPicType = 1;//图片格式：1- jpg，2- bmp，3- png，4- SWF，5- GIF 

                // 人脸图片信息
                int iInputLen = imgStream.Length;
                pstruSendParamIN.pSendData = Marshal.AllocHGlobal(iInputLen);
                Marshal.Copy(imgStream, 0, pstruSendParamIN.pSendData, iInputLen);
                pstruSendParamIN.dwSendDataLen = (uint)iInputLen;

                // 用户xml信息
                long iXMLInputLen = userStream.Length;
                pstruSendParamIN.pSendAppendData = Marshal.AllocHGlobal((int)iXMLInputLen);
                Marshal.Copy(userStream, 0, pstruSendParamIN.pSendAppendData, (int)iXMLInputLen);
                pstruSendParamIN.dwSendAppendDataLen = (uint)iXMLInputLen;

                int dateSize = CHCNetSDK.NET_DVR_UploadSend(lUploadHandle, ref pstruSendParamIN, IntPtr.Zero);
                if (dateSize < 0)
                {
                    return false;
                }
                // 上传流程
                uint pProgress = 0;
                while (pProgress < 100)
                {
                    int iStatus = CHCNetSDK.NET_DVR_GetUploadState(lUploadHandle, ref pProgress);
                    if (iStatus < 0)
                    {
                        break;
                    }
                    else if (iStatus == 2)
                    {
                        continue;
                    }
                    else if (iStatus == 1)
                    {
                        CHCNetSDK.NET_DVR_UPLOAD_FILE_RET struFaceData = new CHCNetSDK.NET_DVR_UPLOAD_FILE_RET();
                        Int32 dwBufferSize = Marshal.SizeOf(struFaceData);
                        IntPtr ptrFaceOut = Marshal.AllocHGlobal(dwBufferSize);
                        if (CHCNetSDK.NET_DVR_GetUploadResult(lUploadHandle, ptrFaceOut, (uint)dwBufferSize))
                            return true;
                        break;
                    }
                    else if (iStatus == 3)
                    {
                        break;
                    }
                    else
                    {
                        break;
                    }
                }
                CHCNetSDK.NET_DVR_UploadClose(lUploadHandle);
            }
            catch { }
            return false;
        }
        public bool UpdateUser(UserCardMQ userCardMQ)
        {
            if (RemovePeopleFace(userCardMQ))
                if (AddUser(userCardMQ))
                    return true;
                
            return false;
        }
        public bool RemovePeopleFace(UserCardMQ cardNum)
        {
            string xmlfile = AppDomain.CurrentDomain.BaseDirectory + "FDSearchDescription.xml";
            string context = null;
            if (File.Exists(xmlfile))
            {
                XmlDocument document = new XmlDocument();
                document.Load(xmlfile);
                XmlNodeList cerNums = document.GetElementsByTagName("certificateNumber");
                cerNums[0].InnerText = cardNum.phone;
                context = document.OuterXml;
                if (string.IsNullOrEmpty(context) == false)
                {
                    string[] strs = new string[2];
                    strs[0] = context.Substring(0, 50);
                    strs[1] = context.Substring(50, context.Length - 50);
                    strs[1] = strs[1].Replace(" ", string.Empty);
                    context = $"{strs[0]}{strs[1]}";
                }
            }
            string outxml = Use_ISAPI("POST /ISAPI/Intelligent/FDLib/FDSearch", context);
            XmlDocument document2 = new XmlDocument();
            document2.LoadXml(outxml);
            XmlNodeList cerNums2 = document2.GetElementsByTagName("status");
            if (cerNums2.Count == 0 || "false".Equals(cerNums2[0].InnerText))
            {
                return false;
            }
            else
            {
                string PID = document2.GetElementsByTagName("PID")[0].InnerText;
                Use_ISAPI("DELETE /ISAPI/Intelligent/FDLib/" + ConfigerService.Device_FaceDatabase_FDID + "/picture/" + PID);
                return true;
            }
        }
        public string Use_ISAPI(string requestUrl, string InputXml = null)
        {
            CHCNetSDK.NET_DVR_XML_CONFIG_INPUT pInputXml = new CHCNetSDK.NET_DVR_XML_CONFIG_INPUT();
            Int32 nInSize = Marshal.SizeOf(pInputXml);
            pInputXml.dwSize = (uint)nInSize;

            string strRequestUrl = requestUrl;
            uint dwRequestUrlLen = (uint)strRequestUrl.Length;
            pInputXml.lpRequestUrl = Marshal.StringToHGlobalAnsi(strRequestUrl);
            pInputXml.dwRequestUrlLen = dwRequestUrlLen;

            string strInputXParam = InputXml;
            if (strInputXParam != null)
            {
                byte[] byInputParam = Encoding.UTF8.GetBytes(strInputXParam);
                int iXMLInputLen = byInputParam.Length;
                pInputXml.lpInBuffer = Marshal.AllocHGlobal(iXMLInputLen);
                Marshal.Copy(byInputParam, 0, pInputXml.lpInBuffer, iXMLInputLen);
                pInputXml.dwInBufferSize = (uint)byInputParam.Length;
            }
            CHCNetSDK.NET_DVR_XML_CONFIG_OUTPUT pOutputXml = new CHCNetSDK.NET_DVR_XML_CONFIG_OUTPUT();
            pOutputXml.dwSize = (uint)Marshal.SizeOf(pOutputXml);
            pOutputXml.lpOutBuffer = Marshal.AllocHGlobal(3 * 1024 * 1024);
            pOutputXml.dwOutBufferSize = 3 * 1024 * 1024;
            pOutputXml.lpStatusBuffer = Marshal.AllocHGlobal(4096 * 4);
            pOutputXml.dwStatusSize = 4096 * 4;

            if (!CHCNetSDK.NET_DVR_STDXMLConfig(Login_Id, ref pInputXml, ref pOutputXml))
            {
                Marshal.FreeHGlobal(pInputXml.lpRequestUrl);
                Marshal.FreeHGlobal(pOutputXml.lpOutBuffer);
                Marshal.FreeHGlobal(pOutputXml.lpStatusBuffer);
                return "<?xml version=\"1.0\" encoding=\"GBK\" ?><status>false</status>";
            }
            else
            {
                byte[] by = new byte[pOutputXml.dwReturnedXMLSize];
                Marshal.Copy(pOutputXml.lpOutBuffer, by, 0, (int)pOutputXml.dwReturnedXMLSize);
                return Encoding.GetEncoding("GBK").GetString(by);
            }
        }
        /// <summary>
        /// 事件回调函数
        /// </summary>
        /// <param name="lCommand"></param>
        /// <param name="pAlarmer"></param>
        /// <param name="pAlarmInfo"></param>
        /// <param name="dwBufLen"></param>
        /// <param name="pUser"></param>
        public static bool Event_Callback(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
           // Console.WriteLine(lCommand);
            switch (lCommand)
            {
                case CHCNetSDK.COMM_SNAP_MATCH_ALARM://人脸比对结果信息
                    ProcessCommAlarm_FaceMatch(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                default:
                    break;
            }
            return true;
        }
        /// <summary>
        /// 登录机器，设置login_id，失败返回-1
        /// </summary>
        /// <returns></returns>
        public static int LoginDevice(string ip, string port, string account, string password)
        {
            CHCNetSDK.NET_DVR_USER_LOGIN_INFO struLoginInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO
            {
                sDeviceAddress = ip,
                sUserName = account,
                sPassword = password,
                wPort = ushort.Parse(port),//设备服务端口号
                bUseAsynLogin = false, //是否异步登录：0- 否，1- 是 
                byLoginMode = 0, //0-Private, 1-ISAPI, 2-自适应
                byHttps = 0 //0-不适用tls，1-使用tls 2-自适应
            };

            CHCNetSDK.NET_DVR_DEVICEINFO_V40 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40();

            return CHCNetSDK.NET_DVR_Login_V40(ref struLoginInfo, ref DeviceInfo);
        }
        private static void ProcessCommAlarm_FaceMatch(ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            CHCNetSDK.NET_VCA_FACESNAP_MATCH_ALARM struFaceMatchAlarm = new CHCNetSDK.NET_VCA_FACESNAP_MATCH_ALARM();
            struFaceMatchAlarm = (CHCNetSDK.NET_VCA_FACESNAP_MATCH_ALARM)Marshal.PtrToStructure(pAlarmInfo, typeof(CHCNetSDK.NET_VCA_FACESNAP_MATCH_ALARM));
            if (struFaceMatchAlarm.byContrastStatus == 1)
                Console.WriteLine("成功");
            else
                Console.WriteLine("失败");
            string name = "";
            string phone = "";
            string pictureUrl = "";
            string pictureName = "";
            //保存抓拍人脸子图图片数据
            if ((struFaceMatchAlarm.struSnapInfo.dwSnapFacePicLen != 0) && (struFaceMatchAlarm.struSnapInfo.pBuffer1 != IntPtr.Zero))
            {
                pictureName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".jpg";
                pictureUrl = ConfigerService.Picture_Url_Prefix + pictureName;
                FileStream fs = new FileStream(pictureUrl, FileMode.Create);
                int iLen = (int)struFaceMatchAlarm.struSnapInfo.dwSnapFacePicLen;
                byte[] by = new byte[iLen];
                Marshal.Copy(struFaceMatchAlarm.struSnapInfo.pBuffer1, by, 0, iLen);
                fs.Write(by, 0, iLen);
                fs.Close();
                if ((struFaceMatchAlarm.struBlackListInfo.dwBlackListPicLen != 0) && (struFaceMatchAlarm.struBlackListInfo.pBuffer1 != IntPtr.Zero)) {
                    CHCNetSDK.NET_VCA_HUMAN_ATTRIBUTE nET_VCA_HUMAN_ATTRIBUTE = struFaceMatchAlarm.struBlackListInfo.struBlackListInfo.struAttribute;
                    name = Encoding.GetEncoding("GBK").GetString(nET_VCA_HUMAN_ATTRIBUTE.byName).TrimEnd('\0');
                    phone = Encoding.GetEncoding("GBK").GetString(nET_VCA_HUMAN_ATTRIBUTE.byCertificateNumber).TrimEnd('\0');
                }
            }
            if (phone.Equals(string.Empty))
                Console.WriteLine("陌生人");
            else
            {
                Console.WriteLine(name);
                //TbRzAlarm tbRzAlarm = new TbRzAlarm();
                //tbRzAlarm.CardNum = phone;
                //tbRzAlarm.Mask =0;
                //tbRzAlarm.UserTemperature = "35";
                //tbRzAlarm.HeadPicture = pictureUrl;
                //tbRzAlarm.Inout = 1;

                //if (!string.Empty.Equals(pictureUrl))
                //{
                //    tbRzAlarm.OssPicture = ConfigerService.ossurlpre + ConfigerService.objectName + pictureName;
                //    OssService.OssUpload(pictureUrl, pictureName);
                //}
                //DataBaseControl.Add_EnterRecord_And_MQ(tbRzAlarm);
                //RabbitMqService.Publish_Local_Message_Async("open", ConfigerService.SheXiangtou_Exchange, ConfigerService.Open_Door);
            }
        }
        public static void Exit(object sender, EventArgs e)
        {
            try
            {
                if (Login_Id != -1)
                {
                    CHCNetSDK.NET_DVR_Logout(Login_Id);
                }
                CHCNetSDK.NET_DVR_Cleanup();
            }
            catch
            {
                Console.WriteLine("SDK释放失败！");
            }
        }
    
    
    
    }
}
